package com.ttbj.payment.original.service.impl;
 
 
import java.util.Comparator;
import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.ttbj.core.util.DateUtils;
import com.ttbj.core.util.HttpClientUtilYH;
import com.ttbj.exception.WebException;
import com.ttbj.payment.config.UrlConfig;
import com.ttbj.payment.original.alipay.config.Configs;
import com.ttbj.payment.original.alipay.model.builder.AlipayTradePrecreateRequestBuilder;
import com.ttbj.payment.original.alipay.result.AlipayF2FPrecreateResult;
import com.ttbj.payment.original.alipay.service.AlipayTradeService;
import com.ttbj.payment.original.alipay.service.impl.AlipayTradeServiceImpl;
import com.ttbj.payment.original.service.OriginalPayService;
import com.ttbj.payment.original.utils.PayUtil;
import com.ttbj.payment.original.wxpay.config.WxPayConfig;
import com.ttbj.payment.original.wxpay.utils.ConfigUtil;
import com.ttbj.payment.original.wxpay.utils.HttpUtil;
import com.ttbj.payment.original.wxpay.utils.PayCommonUtil;
import com.ttbj.payment.original.wxpay.utils.WXPayUtil;
import com.ttbj.payment.original.wxpay.utils.WXUtil;
import com.ttbj.payment.original.wxpay.utils.XMLUtil;
import com.ttbj.util.Assert;
import com.ttbj.util.ResultUtil;
@Component
public class OriginalPayServiceImpl implements OriginalPayService {
	private static final Logger log = LoggerFactory.getLogger(OriginalPayServiceImpl.class);
	private static Long MINUTE_MSEC = 1000l * 60l;
	private static final String EXHIBITION = "兔兔搬家运输费";

	@Override
	public String aliPayNative(String url, Float price, String orderNum, String attach) throws WebException {
		log.info("price :" + price + "  attach :" + attach + "  orderNum : " + orderNum);
		orderNum = PayUtil.orderNumAppend(orderNum);
		String subject = EXHIBITION + orderNum;
		// 卖家支付宝账号ID，用于支持一个签约账号下支持打款到不同的收款账号，(打款到sellerId对应的支付宝账号)
		// 如果该字段为空，则默认为与支付宝签约的商户的PID，也就是appid对应的PID
		String sellerId = Configs.getPid();
		// 订单描述，可以对交易或商品进行一个详细地描述，比如填写"购买商品3件共20.00元"
		String body = attach;
		// (必填) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息 pid
		String storeId = Configs.getPid();
		// 支付超时，线下扫码交易定义为5分钟
		String timeoutExpress = "5m";
		// 获取服务器URL
		String callBackUrl = url + UrlConfig.AL_URL;
		if (price == null || price.equals(0f)) {
			Assert.assertNonNullObj(price, 231, "预下单失败,费用不能为0!");
		}
		String totalAmount = String.valueOf(price);
		// 创建二维码支付请求builder，设置请求参数
		AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder().setOutTradeNo(orderNum).setSubject(subject).setTotalAmount(totalAmount).setSellerId(sellerId).setBody(body).setNotifyUrl(callBackUrl).setTimeoutExpress(timeoutExpress).setStoreId(storeId);
		AlipayTradeService tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();
		// 调用tradePay方法获取当面付应答
		AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);
		switch (result.getTradeStatus()) {
		case SUCCESS:
			AlipayTradePrecreateResponse res = result.getResponse();
			// 获取二维码的URL，返回到前台生成二维码
			String qrCode = res.getQrCode();
			return qrCode;
		case FAILED:
			ResultUtil.throwExcepion(ResultUtil.createFail("messages", 232), "支付宝预下单失败！！！");
			break;
		case UNKNOWN:
			ResultUtil.throwExcepion(ResultUtil.createFail("messages", 232), "系统异常预下单状态未知!!!");
			break;
		default:
			ResultUtil.throwExcepion(ResultUtil.createFail("messages", 232), "不支持的交易状态交易返回异常!!!");
			break;
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	@Override
	public String wxPayNative(String url, Float price, String orderNum, String attach) throws Exception {
		log.info("price :" + price + "  attach :" + attach + "  orderNum : " + orderNum);
		// 订单金额
		String total_fee = WXPayUtil.literalPcice(price);
		if (Assert.isEmpty(total_fee)) {
			Assert.assertNonNullObj(price, 231, "预下单失败,费用不能为0!");
		}
		try {
			orderNum = PayUtil.orderNumAppend(orderNum);
			String key = ConfigUtil.API_KEY;// KEY
			String trade_type = "NATIVE"; // 交易类型，原生扫码支付
			SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
			ConfigUtil.commomParams(packageParams);
			String body = EXHIBITION;// 描述
			// 获取服务器URL
			String callBackUrl = url + UrlConfig.WX_URL;
			packageParams.put("out_trade_no", orderNum);// 订单号
			packageParams.put("body", body); // 商品描述
			packageParams.put("total_fee", total_fee);// 订单金额
			packageParams.put("spbill_create_ip", "127.0.0.1"); // Native支付填调用微信支付API的机器IP
			packageParams.put("trade_type", trade_type); // 交易类型
			packageParams.put("attach", attach); // 附加参数，id的字符串，补交停车费功能使用
			packageParams.put("notify_url", callBackUrl); // 回调地址
			String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
			packageParams.put("sign", sign); // 签名
			String requestXML = PayCommonUtil.getRequestXml(packageParams);
			log.info("微信支付请求参数是：{}",requestXML);
			String resXML = HttpUtil.postData(ConfigUtil.UNIFIEDORDER_URL, requestXML);
			log.info("微信支付返回参数是：{}",resXML);
			Map<String, String> map = XMLUtil.doXMLParse(resXML);
		
			String returnCode = map.get("return_code");
			if ("SUCCESS".equals(returnCode)) {
				String resultCode = map.get("result_code");
				if ("SUCCESS".equals(resultCode)) {
					String urlCode = map.get("code_url"); // 二维码链接
					return urlCode;
				} else {
					String errorCodes = map.get("err_code_des");
					ResultUtil.throwExcepion(ResultUtil.createFail("messages", 232), "订单号：{" + attach + "}生成微信支付码(系统)失败:{" + errorCodes + "}");
				}
			} else {
				String returnMsg = map.get("return_msg");
				ResultUtil.throwExcepion(ResultUtil.createFail("messages", 232), "订单号：{" + attach + "}生成微信支付码(通信)失败:{" + returnMsg + "}");
			}
		} catch (Exception e) {
			ResultUtil.throwExcepion(ResultUtil.createFail("messages", 232), "订单号：{" + attach + "}生成微信支付码失败(系统异常))");
		}
		return null;
	}

	@Override
	public Map<String, String> wxPayJSAPI(String url, Float price, String orderNum, String openId, String attach) throws Exception {
		log.info("price :" + price + " openId :" + openId + " attach :" + attach + " orderNum : " + orderNum);
		String resultXml = null;
		Map<String, String> map = null;
		orderNum = PayUtil.orderNumAppend(orderNum);
		String body = new String(EXHIBITION.getBytes(), "UTF-8");
		// 订单金额
		String fee = WXPayUtil.literalPcice(price);
		if (Assert.isEmpty(fee)) {
			ResultUtil.throwExcepion(ResultUtil.createFail("messages", 231), "支付出现错误支付款不能小于0.01");
		}
		// 请求m
		map = new TreeMap<String, String>(new Comparator<String>() {
			public int compare(String obj1, String obj2) {
				return obj1.compareTo(obj2);// 升序排序
			}
		});
		map.put("appid", WxPayConfig.APPID);
		map.put("attach", attach);
		map.put("mch_id", WxPayConfig.MCH_ID);
		map.put("nonce_str", PayCommonUtil.getNonce_str());
		map.put("body", body);
		map.put("openid", openId);
		map.put("out_trade_no", orderNum);
		map.put("total_fee", fee);
		map.put("spbill_create_ip", "127.0.0.1");
		map.put("notify_url", url + UrlConfig.WX_JSL_URL);
		map.put("trade_type", "JSAPI");// 支付类型
		String date2All = DateUtils.getCurDtsStr();
		map.put("time_start", date2All);
		date2All = DateUtils.getDateTimeStr(new Date(System.currentTimeMillis() + (MINUTE_MSEC * 60L * 2L)));
		map.put("time_expire", date2All);
		String sign = WXUtil.createSign("UTF-8", map);
		map.put("sign", sign);
		String reqStr = WXUtil.getRequestXml(map);
		resultXml = HttpClientUtilYH.sendPost(WxPayConfig.WX_PAY_URL, reqStr);
		System.out.println(" resultXml :" + resultXml);
		// 解析微信返回
		// 如果状态成功 则返回给前端
		String returnCode = WXPayUtil.getReturnCode(resultXml);
		if (returnCode == null || !returnCode.equals(WxPayConfig.SUCCESS)) {
			return null;
		}
		map.clear(); // 清空容器
		map.put("appId", WxPayConfig.APPID);
		map.put("nonceStr", WXPayUtil.getNonceStr(resultXml));// 解析随机字符串
		map.put("package", "prepay_id=" + WXPayUtil.getPrepayId(resultXml));
		map.put("signType", "MD5");
		map.put("timeStamp", String.valueOf((System.currentTimeMillis() / 1000)));// 时间戳
		String paySign = WXPayUtil.getSign(map);
		map.put("paySign", paySign);
		return map;
	}

}
